#ifndef BUFFER_HPP
#define BUFFER_HPP
#include <iostream>
#include <vector>
#include <assert.h>
#define DEFAULT_BUFFER_SIZE 10*1024*1024
#define THRESHOLD_BUFFER_SIZE 80*1024*1024
#define INCREMENT_BUFFER_SIZE 10*1024*1024 
namespace blog
{
    class buffer
    {
    public:
        buffer()
        :_buffer(DEFAULT_BUFFER_SIZE),
        _writter_idx(0),
        _reader_idx(0){}
        //向缓冲区写入
        void push(const char*data,size_t len)
        {
            //检测写入后大小会不会超出缓冲区的上限
            enough_writter(len);
            //写入
            std::copy(data,data+len,&_buffer[_writter_idx]);
            move_writter(len);
        }
        //返回可读数据的起始地址
        const char* begin()
        {
            return &_buffer[_reader_idx];
        }
        //返回可读/写数据的长度
        size_t readAble_len()
        {
            return (_writter_idx-_reader_idx);
        }
        size_t writterAble_len()
        {
            return(_buffer.size()-_writter_idx);
        }
        //移动可读和可写位置 
        void move_writter(size_t len)
        {
            assert(_writter_idx+len<_buffer.size());
            _writter_idx+=len;
        }

        void move_reader(size_t len)
        {
            assert(len<=readAble_len());
            _reader_idx+=len;
        }
        //重置缓冲区
        void reset()
        {
            _writter_idx=0;
            _reader_idx=0;
        }
        //交换缓冲区
        void swap(buffer& buffer)
        {
            _buffer.swap(buffer._buffer);
            std::swap(_writter_idx,buffer._writter_idx);
            std::swap(_reader_idx,buffer._reader_idx);
        }
        bool empty()
        {
            if(_reader_idx==_writter_idx)
            return true;
            return false;
        }
    private:
        void enough_writter(size_t len)
        {
            //空间足够
            if(_writter_idx+len<=writterAble_len())
            {
                return;
            }
            while(_buffer.size()<THRESHOLD_BUFFER_SIZE&&writterAble_len()<len)
            {
                _buffer.resize(2*_buffer.size());
            }
            while(writterAble_len()<len)
            {
                _buffer.resize(_buffer.size()+INCREMENT_BUFFER_SIZE);
            }
        }
    private:
        std::vector<char> _buffer;
        size_t _writter_idx;
        size_t _reader_idx;
    };
}
















#endif